﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Axe
{
    public static partial class Utility
    {
        #region public static string Join(IEnumerable<string> strSource, string joinSymbol)
        /// <summary>
        /// Склеиваем строки
        /// </summary>
        /// <param name="strSource"></param>
        /// <param name="joinSymbol"></param>
        /// <returns></returns>
        public static string Join(IEnumerable<string> strSource, string joinSymbol)
        {
            StringBuilder sb = new StringBuilder();

            int count = 0;

            foreach (string s in strSource)
            {
                sb.Append(s);
                sb.Append(joinSymbol);
                count++;
            }

            if (count > 0)
            {
                int len = joinSymbol.Length;
                sb.Remove(sb.Length - len, len);
            }

            return sb.ToString();
        }
        #endregion

        #region public static string Join(IEnumerable<string> strSource, string joinSymbol, string format)
        /// <summary>
        /// Склеиваем строки
        /// </summary>
        /// <param name="strSource">Массив строк</param>
        /// <param name="joinSymbol">Строка склейки</param>
        /// <param name="format">Формат</param>
        /// <returns></returns>
        public static string Join(IEnumerable<string> strSource, string joinSymbol, string format)
        {
            StringBuilder sb = new StringBuilder();

            int count = 0;

            foreach (string s in strSource)
            {
                sb.Append(String.Format(format, s));
                sb.Append(joinSymbol);
                count++;
            }

            if (count > 0)
            {
                int len = joinSymbol.Length;
                sb.Remove(sb.Length - len, len);
            }

            return sb.ToString();
        }
        #endregion

        #region public static bool Contains<T>(T value, IEnumerable<T> collection)
        public static bool Contains<T>(T value, IEnumerable<T> collection)
        {
            foreach (T Element in collection)
            {
                if (Comparer<T>.Default.Compare(value, Element) == 0)
                    return true;
            }

            return false;
        } 
        #endregion

        #region public static ArrayList BuildArrayList(IEnumerable enumerable)
        public static ArrayList BuildArrayList(System.Collections.IEnumerable enumerable)
        {
            if (enumerable == null)
                return null;

            IEnumerator e = enumerable.GetEnumerator();

            ArrayList list = new ArrayList();

            while (e.MoveNext())
            {
                list.Add(e.Current);
            }

            return list;
        } 
        #endregion

        #region public static TOutputArrayType[] ConvertArray<TInputArrayType, TOutputArrayType>(TInputArrayType[] srcArray) where TOutputArrayType : TInputArrayType
        public static TOutputArrayType[] ConvertArray<TInputArrayType, TOutputArrayType>(TInputArrayType[] srcArray) where TOutputArrayType : TInputArrayType
        {
            int len = srcArray.Length;
            TOutputArrayType[] resArray = new TOutputArrayType[len];

            for (int i = 0; i < len; i++)
            {
                resArray[i] = (TOutputArrayType)(srcArray[i]);
            }

            return resArray;
        } 
        #endregion

        #region public static IEnumerable<TOutputEnumType> CastConvertEnumerable<TInputEnumType, TOutputEnumType>(IEnumerable<TInputEnumType> value)
        public static IEnumerable<TOutputEnumType> CastConvertEnumerable<TInputEnumType, TOutputEnumType>(IEnumerable<TInputEnumType> value)
            where TOutputEnumType : class
            where TInputEnumType : class
        {
            foreach (TInputEnumType input in value)
            {
                yield return input as TOutputEnumType;
            }
        } 
        #endregion

        #region public static List<TOutputListType> CastConvertList<TInputListType, TOutputListType>(List<TInputListType> list) where TOutputListType : TInputListType
        public static List<TOutputListType> CastConvertList<TInputListType, TOutputListType>(List<TInputListType> list) where TOutputListType : TInputListType
        {
            return list.ConvertAll<TOutputListType>(new Converter<TInputListType, TOutputListType>(delegate(TInputListType value) { return (TOutputListType)value; }));
        } 
        #endregion

        #region public static List<TOutput> SafeConvertList<TInput, TOutput>(List<TInput> list) where TOutput : class
        public static List<TOut> SafeConvertList<TIn, TOut>(List<TIn> list) where TOut : class
        {
            List<TOut> output = new List<TOut>(list.Capacity);

            for (int i = 0; i < list.Count; i++)
            {
                TOut t = list[i] as TOut;

                if (t != null)
                    output.Add(t);
            }

            return output;
        } 
        #endregion



        public static bool TryParseEnum<T>(string input, Type enumType, out T value)
            where T:struct
        {
            Type givenType = typeof(T);
            if(givenType.IsEnum == false)
                throw new NotSupportedException("This method supports only enumeration types");

            if (enumType != givenType)
                throw new InvalidOperationException("Types mismatch");

            try
            {
                value = (T)Enum.Parse(enumType, input);
                return true;
            }
            catch (Exception)
            {
                value = default(T);
                return false;
            }

        }

        public static bool TryParseGuid(string text, out Guid value)
        {
            if (String.IsNullOrEmpty(text))
            {
                value = Guid.Empty;
                return false;
            }

            try
            {
                value = new Guid(text);
                return true;
            }
            catch (Exception)
            {
                value = Guid.Empty;
                return false;
            }
        }

    }
}
